// dotenv_ext.h - dotenv扩展库（含混淆/反混淆和JSON导出）
#ifndef DOTENV_EXT_H
#define DOTENV_EXT_H
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 混淆/反混淆模式
#define DOTENV_OBFUSCATE 1   // 混淆模式（加密）
#define DOTENV_DEOBFUSCATE 2 // 反混淆模式（解密）

// 混淆/反混淆结果
typedef enum {
    DOTENV_EXT_SUCCESS = 0,       // 成功
    DOTENV_EXT_FILE_ERROR = -1,   // 文件操作失败
    DOTENV_EXT_KEY_ERROR = -2,    // 密钥无效
    DOTENV_EXT_MEM_ERROR = -3,    // 内存分配失败
    DOTENV_EXT_MODE_ERROR = -4,   // 模式无效
    DOTENV_EXT_TEMP_ERROR = -5,   // 临时文件创建失败
    DOTENV_EXT_JSON_ERROR = -6    // JSON导出错误
} dotenv_ext_result;

// 使用XOR算法混淆/反混淆文件
dotenv_ext_result dotenv_file_transform(
    const char* input_path, 
    const char* output_path, 
    const char* key, 
    int mode
);

// 便捷函数：混淆.env文件
static inline dotenv_ext_result dotenv_obfuscate_file(
    const char* input_path, 
    const char* output_path, 
    const char* key
) {
    return dotenv_file_transform(input_path, output_path, key, DOTENV_OBFUSCATE);
}

// 便捷函数：反混淆.env文件
static inline dotenv_ext_result dotenv_deobfuscate_file(
    const char* input_path, 
    const char* output_path, 
    const char* key
) {
    return dotenv_file_transform(input_path, output_path, key, DOTENV_DEOBFUSCATE);
}

// 从混淆文件加载环境变量
dotenv_ext_result dotenv_load_from_obfuscated(
    const char* obfuscated_path, 
    const char* key, 
    int flags
);

// 将所有环境变量导出为JSON格式文件
dotenv_ext_result dotenv_export_as_json(const char* output_path);

#endif // DOTENV_EXT_H

#ifdef DOTENV_EXT_IMPLEMENTATION

// Windows平台缺失函数的兼容实现
#ifdef _WIN32
// 模拟mktemp功能（兼容Windows）
static char* dotenv_mktemp(char* template) {
    if (!template) return NULL;
    
    // 简单替换模板中的XXXXXX为随机字符
    static const char letters[] = "abcdefghijklmnopqrstuvwxyz0123456789";
    char* XXXXXX = strstr(template, "XXXXXX");
    if (!XXXXXX) return NULL;
    
    for (int i = 0; i < 6; i++) {
        XXXXXX[i] = letters[rand() % (sizeof(letters) - 1)];
    }
    
    // 检查文件是否已存在
    FILE* f = fopen(template, "r");
    if (f) {
        fclose(f);
        return NULL; // 文件已存在，返回失败
    }
    
    return template;
}
#endif

// XOR加密/解密核心函数
static void xor_transform(const char* input, char* output, size_t len, const char* key) {
    if (!input || !output || !key || len == 0) return;
    
    size_t key_len = strlen(key);
    if (key_len == 0) return;
    
    for (size_t i = 0; i < len; i++) {
        output[i] = input[i] ^ key[i % key_len];
    }
}

// 文件混淆/反混淆实现
dotenv_ext_result dotenv_file_transform(
    const char* input_path, 
    const char* output_path, 
    const char* key, 
    int mode
) {
    // 参数校验
    if (!input_path || !output_path || !key || strlen(key) == 0) {
        return DOTENV_EXT_KEY_ERROR;
    }
    
    if (mode != DOTENV_OBFUSCATE && mode != DOTENV_DEOBFUSCATE) {
        return DOTENV_EXT_MODE_ERROR;
    }
     // 调试：打印当前要打开的输入文件路径
    printf("调试：尝试打开文件 - %s\n", input_path);

    // 打开输入文件（二进制模式）
    FILE* in_file = fopen(input_path, "rb");
    if (!in_file) {
         // 详细错误信息：为什么打不开文件
        printf("调试：打开文件失败！路径=%s，错误=%s\n", 
               input_path, strerror(errno));
        return DOTENV_EXT_FILE_ERROR;
    }
    
    // 获取文件大小
    fseek(in_file, 0, SEEK_END);
    long file_size = ftell(in_file);
    fseek(in_file, 0, SEEK_SET);
    
    if (file_size <= 0) {
        fclose(in_file);
        return DOTENV_EXT_FILE_ERROR;
    }
    
    // 分配内存读取文件内容
    char* buffer = (char*)malloc(file_size);
    if (!buffer) {
        fclose(in_file);
        return DOTENV_EXT_MEM_ERROR;
    }
    
    // 读取文件内容
    size_t read_bytes = fread(buffer, 1, file_size, in_file);
    fclose(in_file);
    
    if (read_bytes != (size_t)file_size) {
        free(buffer);
        return DOTENV_EXT_FILE_ERROR;
    }
    
    // 执行XOR转换
    char* output_buffer = (char*)malloc(file_size);
    if (!output_buffer) {
        free(buffer);
        return DOTENV_EXT_MEM_ERROR;
    }
    
    xor_transform(buffer, output_buffer, file_size, key);
    free(buffer);
    
    // 写入输出文件
    FILE* out_file = fopen(output_path, "wb");
    if (!out_file) {
        free(output_buffer);
        return DOTENV_EXT_FILE_ERROR;
    }
    
    size_t written_bytes = fwrite(output_buffer, 1, file_size, out_file);
    fclose(out_file);
    free(output_buffer);
    
    if (written_bytes != (size_t)file_size) {
        return DOTENV_EXT_FILE_ERROR;
    }
    
    return DOTENV_EXT_SUCCESS;
}

// 从混淆文件加载环境变量（修复临时文件创建问题）
dotenv_ext_result dotenv_load_from_obfuscated(
    const char* obfuscated_path, 
    const char* key, 
    int flags
) {
    char temp_path[256];
    int retries = 0;
    const char* temp_templates[] = {
        "/tmp/dotenv_XXXXXX",      // Unix系统
        "./dotenv_XXXXXX",         // 当前目录（备选）
        "dotenv_XXXXXX"            // 简单文件名（最后尝试）
    };
    const int num_templates = sizeof(temp_templates) / sizeof(temp_templates[0]);
    int temp_created = 0;

    // 初始化随机数生成器（用于临时文件名）
    srand((unsigned int)time(NULL));

    // 循环尝试不同的临时路径模板
    while (retries < num_templates) {
        const char* template = temp_templates[retries];
        retries++;

        // 复制模板路径
        strncpy(temp_path, template, sizeof(temp_path) - 1);
        temp_path[sizeof(temp_path) - 1] = '\0';

        // 跨平台创建临时文件
#ifdef _WIN32
        // Windows平台：使用自定义的dotenv_mktemp
        if (dotenv_mktemp(temp_path)) {
            // 验证文件是否不存在
            FILE* test = fopen(temp_path, "r");
            if (!test) {
                temp_created = 1;
            } else {
                fclose(test);
            }
        }
#else
        // Unix/Linux平台：使用标准mkstemp
        int fd = mkstemp(temp_path);
        if (fd != -1) {
            close(fd);
            temp_created = 1;
        }
#endif

        if (temp_created) break;
    }

    // 检查临时文件是否创建成功
    if (!temp_created) {
        fprintf(stderr, "临时文件创建失败！请检查目录权限\n");
        return DOTENV_EXT_TEMP_ERROR;
    }

    // 反混淆到临时文件
    dotenv_ext_result result = dotenv_deobfuscate_file(obfuscated_path, temp_path, key);
    if (result != DOTENV_EXT_SUCCESS) {
        remove(temp_path);
        return result;
    }

    // 加载临时文件
    dotenv_load_from_file(temp_path, flags);

    // 清理临时文件
    remove(temp_path);

    return DOTENV_EXT_SUCCESS;
}

// 将所有环境变量导出为JSON格式
dotenv_ext_result dotenv_export_as_json(const char* output_path) {
    if (!output_path) {
        return DOTENV_EXT_FILE_ERROR;
    }

    // 打开输出文件
    FILE* out_file = fopen(output_path, "w");
    if (!out_file) {
        return DOTENV_EXT_FILE_ERROR;
    }

    // 写入JSON开头
    fprintf(out_file, "{\n");

    // 迭代所有环境变量
    size_t var_count = dotenv_count_vars();
    for (size_t i = 0; i < var_count; i++) {
        const char* key;
        const char* value;
        if (dotenv_iter(i, &key, &value)) {
            // 写入JSON键值对（处理字符串转义）
            fprintf(out_file, "  \"%s\": \"%s\"", key, value);
            
            // 最后一个元素不加逗号
            if (i != var_count - 1) {
                fprintf(out_file, ",");
            }
            fprintf(out_file, "\n");
        }
    }

    // 写入JSON结尾
    fprintf(out_file, "}\n");
    fclose(out_file);

    return DOTENV_EXT_SUCCESS;
}

#endif // DOTENV_EXT_IMPLEMENTATION